package ext.vpde.cadvaulting.revise.processors.table;

import com.ptc.windchill.enterprise.revise.processors.table.*;
import ext.vpde.cadvaulting.util.WpHelperUtility;
import wt.doc.WTDocument;
import wt.epm.EPMDocument;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

import wt.change2.ChangeHelper2;
import wt.enterprise.RevisionControlled;
import wt.facade.netmarkets.NetmarketsHref;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTCollection;
import wt.fc.collections.WTKeyedHashMap;
import wt.fc.collections.WTKeyedMap;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainer;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.PhaseSuccession;
import wt.lifecycle.State;
import wt.lifecycle.Transition;
import wt.org.WTUser;
import wt.preference.PreferenceHelper;
import wt.series.Series;
import wt.series.SeriesException;
import wt.session.SessionHelper;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.util.WTPropertyVetoException;
import wt.vc.VersionControlException;
import wt.vc.VersionControlHelper;
import wt.vc.Versioned;
import wt.folder.Foldered;

import com.ptc.windchill.cadx.NewEPMDocument;
import com.ptc.core.htmlcomp.collection.presentation.UICollectionJSTableProcessor;
import com.ptc.core.htmlcomp.jstable.JSActionIconPropertyValues;
import com.ptc.core.htmlcomp.jstable.JSActionPropertyValue;
import com.ptc.core.htmlcomp.jstable.JSBooleanPropertyValue;
import com.ptc.core.htmlcomp.jstable.JSColumnDescriptor;
import com.ptc.core.htmlcomp.jstable.JSDataHandler;
import com.ptc.core.htmlcomp.jstable.JSDataObject;
import com.ptc.core.htmlcomp.jstable.JSIntegerPropertyValue;
import com.ptc.core.htmlcomp.jstable.JSPersistableDataUtility;
import com.ptc.core.htmlcomp.jstable.JSPropertyDataConstants;
import com.ptc.core.htmlcomp.jstable.JSPropertyValue;
import com.ptc.core.htmlcomp.jstable.JSStandardColumnDescriptorFactory;
import com.ptc.core.htmlcomp.jstable.JSStatusColumnHelper;
import com.ptc.core.htmlcomp.jstable.JSStringPropertyValue;
import com.ptc.core.htmlcomp.jstable.JSTableDescriptor;
import com.ptc.core.htmlcomp.jstable.ServerStatus;
import com.ptc.core.htmlcomp.util.DataValidator;
import com.ptc.core.htmlcomp.util.SeedObjectsUtilities;
import com.ptc.core.logging.Log;
import com.ptc.core.logging.LogFactory;
import com.ptc.windchill.cadx.common.util.GenericUtilities;
import com.ptc.windchill.cadx.ws.wsResource;
import com.ptc.windchill.enterprise.revise.ReviseConstants;
import com.ptc.windchill.enterprise.revise.ReviseHelper;
import com.ptc.windchill.enterprise.revise.reviseResource;
import com.ptc.windchill.enterprise.revise.validators.ReviseJSDataValidator;


public class WPReviseJSTableProcessor extends UICollectionJSTableProcessor implements ReviseConstants {

	private static final String RESOURCE = "com.ptc.windchill.enterprise.revise.reviseResource";
	private static final String RESOURCEWS = "com.ptc.windchill.cadx.ws.wsResource";

	private static Log log = LogFactory.getLog(WPReviseJSTableProcessor.class.getName());

	private Map transitionsMasterList = null;
	private Map revisionPrefMasterList = null;

	private WTCollection existingHangingChangeMasterList = null;

	protected static final String ACTION_REFERENCE = "reference";

	protected static final String ACTION_DEFER = "defer";

	protected static final String SPACE_IMAGE = "netmarkets/images/sp.gif";

	protected static final String DEFER_STATUS_IMAGE = "com/ptc/core/htmlcomp/images/new9x9.gif";


	@SuppressWarnings("deprecation")
	public JSTableDescriptor getTableDescriptor(String tableId, Properties properties, Locale locale) {

		if (log.isTraceEnabled())
		    log.trace(" input tableid is: " + tableId);

		JSTableDescriptor tabledesc = new JSTableDescriptor(tableId);
		tabledesc.setJSDataUtility(getJSDataUtility());
		JSStandardColumnDescriptorFactory columnFactory = new JSStandardColumnDescriptorFactory();

		tabledesc.setSelectionEnabled(true);
		JSDataHandler handler = null;

		/***********************************************************************
		 * ******** COLUMN LIST FOR REVISE TABLE ************
		 **********************************************************************/

		// set default for sorting columns
		tabledesc.setDefaultSortColumn(JSPropertyDataConstants.NUMBER_JSID);

		// message and server status and actionstatus set to true
		JSStatusColumnHelper.addStatusColumnsToTable(tabledesc, true, true, false, false, true,
				false, true, locale, JSStatusColumnHelper.SHOW_ALL_STATUS);

		// obj type
		tabledesc.addColumn(columnFactory.newTypeIconColumn(locale, false));

		// number
		tabledesc.addColumn(columnFactory.newNumberColumn(locale, false));

		// version (iteration)
		tabledesc.addColumn(columnFactory.newIterationColumn(locale, false));

		// actions column - information page icon as popup
		JSColumnDescriptor columnAction = new JSColumnDescriptor((JSPropertyDataConstants.DETAILS_ACTION_JSID),
						WTMessage.getLocalizedMessage(RESOURCEWS, wsResource.VIEW_DETAILS_ACTION, null, locale),
				18, true);
					handler = new ActionColumnJSDataHandler();
		tabledesc.addJSDataHandler(JSPropertyDataConstants.DETAILS_ACTION_JSID, handler);
		tabledesc.addColumn(columnAction);


		// only show org is property is set
		if (GenericUtilities.isOrganizationExposed()) {
			tabledesc.addColumn(columnFactory.newOrganizationColumn(locale, false));
		}

    // team column
    String label = WTMessage.getLocalizedMessage(RESOURCE, reviseResource.TEAM, null, locale);
    JSColumnDescriptor teamColumn = new JSColumnDescriptor(ReviseConstants.TEAM_COLUMN_ID, label, false);
    teamColumn.addDataAttribute(ReviseConstants.TEAM_COLUMN_ID);
    tabledesc.addJSDataHandler(ReviseConstants.TEAM_COLUMN_ID, new TeamJSDataHandler());
    tabledesc.addColumn(teamColumn);

		// name
		tabledesc.addColumn(columnFactory.newNameColumn(locale, false));

		/***********************************************************************
		 * ************ NEW REVISION LABEL COLUMN *************
		 **********************************************************************/

		log.trace(" adding New Revision column");

		JSColumnDescriptor column = new JSColumnDescriptor(ReviseConstants.NEW_REVISION_COLUMN_ID,
				WTMessage.getLocalizedMessage(RESOURCE, reviseResource.NEW_REVISION, null, locale),
				18, true);

		column.setAttrRenderer(ReviseConstants.RENDER_REVISIONLABEL);
		tabledesc.addDataAttribute(ReviseConstants.VERSION_JSID);
		column.addDataAttribute(ReviseConstants.NEW_REVISION_COLUMN_ID);
		handler = new NewRevisionJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.NEW_REVISION_COLUMN_ID, handler);

		column.addDataAttribute(ReviseConstants.OBJ_WEIGHTAGE);
		handler = new WeightageJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.OBJ_WEIGHTAGE, handler);

		column.addDataAttribute(ReviseConstants.ISNEWOBJ);
		handler = new IsNewObjJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.ISNEWOBJ, handler);
		tabledesc.addFormAttribute(ReviseConstants.ISNEWOBJ);
		tabledesc.addFormAttribute(ReviseConstants.NEW_REVISION_COLUMN_ID);


		//need to check the container level preference to see if the field can be enabled
		column.addDataAttribute(ReviseConstants.ISREVISIONOVERRIDEALLOWED);
		handler = new IsRevisionOverrideAllowedJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.ISREVISIONOVERRIDEALLOWED, handler);
		tabledesc.addFormAttribute(ReviseConstants.ISREVISIONOVERRIDEALLOWED);
		tabledesc.addFormAttribute(ReviseConstants.NEW_REVISION_COLUMN_ID);


		column.setSortable(true);
		tabledesc.addColumn(column);

		/*
		 * ********** END - NEW REVISION LABEL COLUMN
		 */

		/***********************************************************************
		 * ************ NEW LOCATION LABEL COLUMN *************
		 **********************************************************************/

		// Using standard property for LOCATION instead of user defined
		// property.
		log.trace(" adding New Location Column");

		JSColumnDescriptor newLocationColumn = new JSColumnDescriptor(
				ReviseConstants.LOCATION_COLUMN_ID, WTMessage.getLocalizedMessage(RESOURCE,
						reviseResource.NEW_LOCATION, null, locale), 18, true);
		newLocationColumn.setAttrRenderer(ReviseConstants.RENDER_REVISELOCATION);
		tabledesc.addColumn(newLocationColumn);
		tabledesc.addFormAttribute(JSPropertyDataConstants.NEWFOLDEROID_JSID);
		tabledesc.addFormAttribute(JSPropertyDataConstants.LOCATION_JSID);
		tabledesc.addDataAttribute(JSPropertyDataConstants.CONTEXTOID_JSID);

		column.addDataAttribute(ReviseConstants.ISNOTFOLDERED);
		handler = new IsNotFolderedObjJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.ISNOTFOLDERED, handler);
		tabledesc.addFormAttribute(ReviseConstants.ISNOTFOLDERED);
		tabledesc.addFormAttribute(ReviseConstants.LOCATION_COLUMN_ID);


		/*
		 * ********** END - NEW LOCATION LABEL COLUMN
		 */

		// NEW STATE COLUMN - shows the next state based upon revise transition
		log.trace(" adding New State Column");
		column = new JSColumnDescriptor(ReviseConstants.NEW_STATE, WTMessage.getLocalizedMessage(
				RESOURCE, reviseResource.NEW_STATE, null, locale), 18, false);

		// column.addDataAttribute(LIFECYCLE_DATA);
		handler = new LifecycleStatesDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.NEW_STATE, handler);
		// tabledesc.addJSDataHandler(LIFECYCLE_DATA, handler);
		column.setSortable(true);
		tabledesc.addColumn(column);

		// COLLECTION RULE COLUMN
		tabledesc.addColumn(columnFactory.newCollectionRulesColumn(locale, false));

		/***********************************************************************
		 * ******* DEFER (AKA HANGING CHANGE) DATA ATTRIBUTES *******
		 **********************************************************************/

		tabledesc.addDataAttribute(ReviseConstants.NEWHANGINGCHANGE_JSID);
		tabledesc.addDataAttribute(ReviseConstants.EXISTINGHANGINGSTATUS_JSID);

		tabledesc.addDataAttribute(ReviseConstants.DEFER_JSID);

		JSActionIconPropertyValues actionIcons = new JSActionIconPropertyValues();
		actionIcons
				.addActionIconItem(ACTION_DEFER, WTMessage.getLocalizedMessage(RESOURCE,
						reviseResource.DEFER_ACTION, null, locale),
						DEFER_STATUS_IMAGE, null);
		actionIcons.addActionIconItem(ACTION_REFERENCE, "",SPACE_IMAGE, null);

		handler = new ActionStatusJSDataHandler();
		tabledesc.addJSDataHandler(JSPropertyDataConstants.ACTION_STATUS_JSID, handler);
		tabledesc.addEnumValuesHelper(JSPropertyDataConstants.ACTION_STATUS_JSID, actionIcons);

		JSColumnDescriptor columnDefer = new JSColumnDescriptor("defer", "", 1, false);
	    columnDefer.addEnumValuesHelper("defer", actionIcons);
	    columnDefer.setAttrRenderer("renderTDActionStatus");
	    tabledesc.addColumn(columnDefer);

		handler = new IsExistingHangingChangeJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.DEFERRABLE_TYPE_JSID, handler);

		// Hanging Changes can be against any object type
		handler = new IsDeferrableTypeJSDataHandler();
		tabledesc.addJSDataHandler(ReviseConstants.DEFERRABLE_TYPE_JSID, handler);
		tabledesc.addFormAttribute(ReviseConstants.DEFERRABLE_TYPE_JSID);

		tabledesc.addDataAttribute(ReviseConstants.EXISTINGHANGINGSTATUS_JSID);

		tabledesc.setToolBar("ReviseToolBar");
		return tabledesc;

	}

	@Override
	public DataValidator getDataValidator() {
		return new ReviseJSDataValidator();
	}

	class IsExistingHangingChangeJSDataHandler implements JSDataHandler {
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
			WTCollection persistables = (WTCollection) SeedObjectsUtilities
					.getPersistables(dataObjects);
			existingHangingChangeMasterList = getExistingHangingChangeMap(persistables);
		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {
			boolean isExistingHC = false;

			log.trace(" Existing Hanging Change Data Handler");
			Iterator<Persistable> iter = existingHangingChangeMasterList.iterator();
			while (iter.hasNext()) {
				Persistable existingHC = iter.next();
				if (existingHC.equals(object)) {
					// row object is found in collection of objects with a
					// existing hanging change
					isExistingHC = true;
				}
			}

			return new JSBooleanPropertyValue(isExistingHC);
		}
	}

   //////////////////////////////////////////////////////////////////////////////////////////
	class ActionStatusJSDataHandler implements JSDataHandler {
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
	 }

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {
            //initial values will be set in the page

                return new JSStringPropertyValue(WPReviseJSTableProcessor.ACTION_REFERENCE);


        }
	}

	//////////////////////////////////////////////////////////////////////////////////////////
		class ActionColumnJSDataHandler extends JSPersistableDataUtility implements JSDataHandler{
			public void init(String attribute, Locale locale, List dataObjects) throws WTException {
		 }

			public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
					JSDataObject jsObject) throws WTException {
	            //initial values will be set in the page

				 if (attribute.equals(JSPropertyDataConstants.DETAILS_ACTION_JSID))
		            {
					 return new JSActionPropertyValue(attribute, ReviseHelper.getPopUpHref(ReviseHelper.getDetailsHref(object)), true);

		            }
		            return new JSStringPropertyValue();
		         }


	 }


	public WTCollection getExistingHangingChangeMap(WTCollection objects) throws WTException {

		log.trace("The component id was a reviseImpact component.");
		existingHangingChangeMasterList = ChangeHelper2.service.hasHangingChanges(objects);
        if (log.isTraceEnabled())
            log.trace("existing hanging changes determined: " + existingHangingChangeMasterList);

		return existingHangingChangeMasterList;
	}

	class NewRevisionJSDataHandler implements JSDataHandler {
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {

		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {
			String value = "";
			try {
				//set the series
				log.trace(" New Revision Data Handler");
				if (object instanceof Versioned) {
					Series s = VersionControlHelper.getVersionIdentifier((Versioned) object)
							.getSeries();

					if (s != null) {
						s.increment();
						value = s.getValue();
					}
                    try{
						if (( object instanceof EPMDocument || object instanceof WTDocument) && !WpHelperUtility.isStandard((Versioned)object))
						{
							value = WpHelperUtility.mapVersion(value);
						}
					}catch (Exception e){e.printStackTrace();}
                    if (log.isTraceEnabled())
                        log.trace(" New Revision Data Handler s: " + value);
				}


			} catch (SeriesException se) { se.printStackTrace();
			} catch (VersionControlException vce) { vce.printStackTrace();
			} catch (WTPropertyVetoException wtpve) { wtpve.printStackTrace();
			}

			return new JSStringPropertyValue(value);
		}

	}

	class IsRevisionOverrideAllowedJSDataHandler implements JSDataHandler {
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
			Collection persistables = SeedObjectsUtilities.getPersistables(dataObjects);
			revisionPrefMasterList = getRevisionPrefMap(persistables);
			log.trace("revisionPrefMasterList");

		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {

			//default to false
			boolean isRevisionAllowed = false;

			if (revisionPrefMasterList != null && object instanceof Persistable && revisionPrefMasterList.containsKey(object)) {
			// find the map of transitions for given object
				 isRevisionAllowed =  Boolean.parseBoolean (revisionPrefMasterList.get(object).toString());
			}
			return new JSBooleanPropertyValue(isRevisionAllowed);
		}


		private Map getRevisionPrefMap(Collection objects) throws WTException {

			log.trace("Building Revision Preference Map.");
			Map revMap = new HashMap();
			WTContainer container = null;

			//default is false
			Boolean isRevisionOverridedAllowed = false;

			Iterator<Versioned> iter = objects.iterator();
			while (iter.hasNext()) {
				WTUser user = (WTUser) SessionHelper.getPrincipal();
                Object obj = iter.next();
                if (obj instanceof Versioned)
                {
    				Versioned object = (Versioned)obj;
    				//get the container of the object
    				if (object instanceof WTContained) {
			            if (object instanceof WTContainer) {
			               container = (WTContainer) object;
			            } else {
			               container = ((WTContained) object).getContainer();
			            }

			            // see if for this container revision label overrrides are allowed
			            // this will control whether the "New Revision" column will appear as a texbox
			            // and  whether the Find Revision toolbar action will allow updates for a given row
			        	isRevisionOverridedAllowed = (Boolean) PreferenceHelper.service.getValue(
								ReviseConstants.REVISIONOVERRIDEALLOWEDPREF, container, user);

			        	//default to false
			        	if (isRevisionOverridedAllowed == null) {
			        		isRevisionOverridedAllowed = false;
			        	}

			        	revMap.put(object,isRevisionOverridedAllowed);

			         }
    			}
            }
            if (log.isTraceEnabled())
                log.trace("RevisionMap: " + revMap);

			return revMap;
		}
}

	class WeightageJSDataHandler implements JSDataHandler {
		Map objWt = new HashMap();

		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
			// sort order based on revision if setTargetRevision rule is true
			Vector tmp = new Vector();
			tmp.addAll(dataObjects);
			Map sortedMap = segregateAndSortVersionedObjs(tmp);
			Vector sortedObjsToRevise = new Vector();

			for (Iterator i = sortedMap.values().iterator(); i.hasNext();) {

				  sortedObjsToRevise.addAll((Collection) i.next());

			}

			for (int j = 0; j < sortedObjsToRevise.size(); j++) {
				objWt.put(sortedObjsToRevise.get(j), new Integer(j));
			}

		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {
			Integer objWeightage = null;
			if (objWt != null && objWt.containsKey(object))
				objWeightage = (Integer) objWt.get(object);

			return new JSIntegerPropertyValue(objWeightage);
		}

		private Vector pushElementInSortedOrder(Object obj, Vector srcVector) {
			if (srcVector == null)
				srcVector = new Vector();

			int insertionIndex = srcVector.size();
			for (int i = 0; i < srcVector.size(); i++) {
				if (isGreaterThan((Versioned) obj, (Versioned) srcVector.elementAt(i))) {
					insertionIndex = i;
					break;
				}
			}

			srcVector.add(insertionIndex, obj);
			return srcVector;
		}

		private boolean isGreaterThan(Versioned obj1, Versioned obj2) {
			try {
				Series s1 = VersionControlHelper.getVersionIdentifier(obj1).getSeries();
				Series s2 = VersionControlHelper.getVersionIdentifier(obj2).getSeries();
				return (!s1.lessThan(s2));
			} catch (VersionControlException vce) {
				// not likely go get here
			}

			return false;
		}

		private Map segregateAndSortVersionedObjs(Vector versionedObjs) {
			Map ret = new HashMap();
			for (int i = 0; i < versionedObjs.size(); i++) {
				Object seriesKey = null;
				String seriesStr = "0";
				Vector objsBucket = null;
				Object tmpObj = versionedObjs.elementAt(i);
				if (tmpObj instanceof Versioned) {
					try {
						seriesStr = VersionControlHelper.getSeriesKey((Versioned) versionedObjs
								.elementAt(i));
					} catch (VersionControlException vce) {
					}

					seriesKey = new Integer(seriesStr.hashCode());
					objsBucket = pushElementInSortedOrder(versionedObjs.elementAt(i), (Vector) ret
							.get(seriesKey));

					ret.put(seriesKey, objsBucket);
				}

			}

			return ret;
		}
	}

	class IsNewObjJSDataHandler implements JSDataHandler {
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {
			String serverStatus = ((JSStringPropertyValue) jsObject
					.getAttributeValue(JSPropertyDataConstants.SERVER_STATUS_JSID)).getValue();
			boolean isNewObj = ServerStatus.NEW_OBJECT.toString().equals(serverStatus);
            if (log.isTraceEnabled())
                log.trace("object is " + object + "\t isNewObj is " + isNewObj);
			return new JSBooleanPropertyValue(isNewObj);
		}
	}


		class IsNotFolderedObjJSDataHandler implements JSDataHandler {
			public void init(String attribute, Locale locale, List dataObjects) throws WTException {
			}

			public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
					JSDataObject jsObject) {

				boolean isNotFolderedObj = false;

				if (!(object instanceof Foldered)) {
					isNotFolderedObj = true;    // location field will not be available for non-foldered
				}

                if (log.isTraceEnabled())
                    log.trace("object is " + object + "\t isNotFolderedObj is " + isNotFolderedObj);

                return new JSBooleanPropertyValue(isNotFolderedObj);
			}
	}

	class IsDeferrableTypeJSDataHandler implements JSDataHandler {
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) {

			//All types can be deferrable
			return new JSBooleanPropertyValue(true);
		}
	}

	class LifecycleStatesDataHandler implements JSDataHandler {
		// Transition map will hold a map of objects where the key is the object
		// for which we want the states and the value is a Set of Lifecycle
		// States
		public void init(String attribute, Locale locale, List dataObjects) throws WTException {
			System.out.println("*** getting seed objects ***");
			Collection persistables = SeedObjectsUtilities.getPersistables(dataObjects);
			transitionsMasterList = getTransitionsMap(persistables);
			log.trace("transitionsMasterList");
		}

		public JSPropertyValue getJSPropertyValue(String attribute, Locale locale, Object object,
				JSDataObject jsObject) throws WTException
				{

			boolean found = false;
			String stateString = "";
			if ((object instanceof wt.lifecycle.LifeCycleManaged) && !(object instanceof com.ptc.windchill.cadx.NewEPMDocument)) {

			  // find the map of transitions for given object
        	  if (transitionsMasterList != null)
			  {
                WTKeyedHashMap transitionsMap = (WTKeyedHashMap) transitionsMasterList.get(object);
                if (transitionsMap != null) {
                	log.trace("There was one or more transitions defined in the transition map.");
                	Iterator kit = transitionsMap.wtKeySet().persistableIterator();
                	WTArrayList phasesForObject = (WTArrayList) transitionsMap.get(kit.next());
                	if (!phasesForObject.isEmpty()) {
                		// phases: should only be one returned
                        if (log.isTraceEnabled())
                            log.trace("The phases array is not empty size: " + phasesForObject.size());

                		for (Iterator phaseIter = phasesForObject.iterator(); phaseIter.hasNext();) {
                			ObjectReference objRef = (ObjectReference) phaseIter.next();
                			PhaseSuccession phase = (PhaseSuccession) objRef.getObject();
                			State stateLoop = phase.getSuccessor().getPhaseState();
                            if (log.isTraceEnabled())
                                log.trace("new revise state:  " + stateLoop.getStringValue());
                			stateString = stateLoop.getDisplay(locale);
                			if (stateString != "") {
                				found = true;
                				break;
                			}
                		}
                	}
                }
              }
			}
			if (!found) {
			  //error
			}

			return new JSStringPropertyValue(stateString);
		}


public Map getTransitionsMap(Collection objects) throws WTException {

		log.trace("Building Transition Map");
		WTKeyedMap tranMap = new WTKeyedHashMap();
		Iterator<LifeCycleManaged> iter = objects.iterator();
		while (iter.hasNext()) {
			Object obj = iter.next();
			if (obj instanceof LifeCycleManaged)
			{
    			LifeCycleManaged lcm = (LifeCycleManaged)obj;
    			Set set = new HashSet();
    			set.add(lcm.getState().getState());

                if (log.isTraceEnabled())
                    log.trace("adding" + lcm.getState().getState() + " to map for: " + lcm);

    			tranMap.put(lcm, set);
			}
		}
		transitionsMasterList = (WTKeyedHashMap) LifeCycleHelper.service.navigate(tranMap,
				Transition.REVISE, true);

        if (log.isTraceEnabled())
            log.trace("transitions calculated: " + transitionsMasterList);

		return transitionsMasterList;
	}
 }

  class TeamJSDataHandler implements JSDataHandler
  {
    public void init(String attribute, Locale locale, List dataObjects) throws WTException
    {
    }

    public JSPropertyValue getJSPropertyValue (String attribute, Locale locale, Object object, JSDataObject jsObject)
    {
      if (object instanceof RevisionControlled){
            RevisionControlled vcObj = (RevisionControlled)object;

            String strTeam = vcObj.getTeamTemplateName();

            if (strTeam == null)
              strTeam = "";

            if (log.isTraceEnabled())
                log.trace("team is "+ strTeam);

            return new JSStringPropertyValue(strTeam);
      }
      return null;
    }
  }
}

